package com.beantools.filters;

import com.beantools.entity.EntityStorage;
import com.beantools.util.ArrayUtil;
import com.beantools.util.poutil.MethodUtil;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Set;

import static com.beantools.constants.FrameConstant.SYSTEM_CLASS;
import static com.beantools.constants.MethodPrefix.PREFIX_GET;
import static com.beantools.constants.MethodPrefix.PREFIX_SET;
import static com.beantools.util.ObjectUtil.isNotNull;
import static com.beantools.util.StringUtil.isNotBlank;

/**
 * 这是方法过滤器，继承抽象类AbstractFilters，其有两个泛型对象。
 * <p>
 * Property对象{@link EntityStorage}，存储属性民称、
 * 属性类型、方法对象，这也是过滤后的属性
 * <p>
 * Method 方法对象{@link java.lang.reflect.Method}方法对象
 *
 * @author baoya
 * @version 1.0
 * @since 1.1.0
 * @see BuilderFilters
 */
public class MethodFilters extends AbstractFilters<EntityStorage, Method> implements Serializable {

    private static final long serialVersionUID = 1640587640377013453L;

    protected MethodFilters() {

    }

    /**
     * 对象方法的数组,该数组包括继承父类在内的所有方法。通过分解方法，
     * 获取方法中的属性，包括父类的属性，来验证属性是否符合规则。
     *
     * @param methods 方法数组
     * @param flag    过滤条件，此处可以为set、get、is字段
     * @return 过滤后的属性对象
     */
    @Override
    public Set<EntityStorage> filter(Method[] methods, String flag) {
        if (ArrayUtil.isEmpty(methods)) {
            return null;
        }
        Set<EntityStorage> properties = new LinkedHashSet<>();
        for (Method method : methods) {
            EntityStorage propertyEntity = filter(method, flag);
            if (isNotNull(propertyEntity)) {
                properties.add(propertyEntity);
            }
        }
        return properties;
    }

    /**
     * 获取Property对象
     *
     * @param method 方法
     * @param flag   过滤条件，此处可以为set、get、is字段
     * @return null or Property对象
     */
    public EntityStorage filter(Method method, String flag) {
        String propertyName = MethodUtil.methodTransformProperty(method, flag);
        EntityStorage propertyEntity = null;
        if (isNotBlank(propertyName)) {
//                如果是get方法获取，遇到class字符，则跳过
            if (SYSTEM_CLASS.equals(propertyName)) {
                return null;
            }
            propertyEntity = new EntityStorage(propertyName, method.getReturnType(), method);
        }
        return propertyEntity;
    }

    /**
     * 对象方法的数组,该数组包括继承父类在内的所有方法。通过get方法
     * 或者is方法，获取方法中的属性，包括父类的属性，来验证属性是否符合规则。
     *
     * @param methods 方法数组
     * @return 过滤后的属性对象的set集合
     */
    public Set<EntityStorage> filterByGetter(Method[] methods) {
        return filter(methods, PREFIX_GET);
    }

    /**
     * 对象方法,该数组包括继承父类在内的所有方法。通过get方法
     * 或者is方法，获取方法中的属性，包括父类的属性，来验证属性是否符合规则。
     *
     * @param method 方法
     * @return 过滤后的属性对象
     */
    public EntityStorage filterByGetter(Method method) {
        return filter(method, PREFIX_GET);
    }


    /**
     * 对象方法的数组,该数组包括继承父类在内的所有方法。通过分解set方法，
     * 获取方法中的属性，包括父类的属性，来验证属性是否符合规则。
     *
     * @param methods 方法数组
     * @return 过滤后的属性对象
     */
    public Set<EntityStorage> filterBySetter(Method[] methods) {
        return filter(methods, PREFIX_SET);
    }

    /**
     * 对象方法,该数组包括继承父类在内的所有方法。通过分解set方法，
     * 获取方法中的属性，包括父类的属性，来验证属性是否符合规则。
     *
     * @param method 方法
     * @return 过滤后的属性对象
     */
    public EntityStorage filterBySetter(Method method) {
        return filter(method, PREFIX_SET);
    }
}
